/*	CS362 Team 8 - Darren Mui, Preson Skaggs
	Goal: 100% Statement/Branch Coverage

 */

#include "dominion.h"
#include "dominion_helpers.h"
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include "rngs.h"

#define NUM_TESTS 10000

int main() {
	int currPlayer, numPlayer;
    int x, p, r;
	int i, j;
	int testCount, testPassed, testFailed;
	int fixedCounter; // counter for the 5 fixed tests
    int k[10];
	int handPos, c1, c2, c3;
    struct gameState G;

	SelectStream(2);
	PutSeed(3);

	testPassed = 0;
	testFailed = 0;

    printf ("TESTING playCard():\n");
    for (testCount = 0; testCount < NUM_TESTS; testCount++) {

		//randomize the 10 kingdom cards from adventurer to treasure_map
		for (i = 0; i < 10; i++) {
			k[i] = floor( (Random() * (treasure_map - adventurer + 1)) + adventurer);
		}	
		//randomize duplicates until there are no more duplicate kingdom cards
		for (i = 0; i < 10; i++) {
			for (j = 0; j < 10; j++) {
				while (k[i] == k[j] && i != j) {
					k[i] = floor( (Random() * (treasure_map - adventurer + 1)) + adventurer);
					j = 0;
				}
			}
		}

		// randomize number of players between 0 to MAX_PLAYERS
		do {
			numPlayer = floor(Random() * MAX_PLAYERS + 1);
		} while (numPlayer < 2);

		memset(&G, 23, sizeof(struct gameState));   // clear the game state
		r = initializeGame(numPlayer, k, floor(Random() * 256), &G); // initialize a new game

		// randomize whose turn it is
		p = floor(Random() * G.numPlayers); 
		G.whoseTurn = p;

		// randomize deck, discard, and hand of every player
		for (currPlayer = 0; currPlayer < G.numPlayers; currPlayer++) {
			G.deckCount[currPlayer] = floor(Random() * MAX_DECK); // randomize # of cards in deck for player
			//set each card in the player deck to a random card from curse to treasure_map (based on the enum in dominion.h)
			for (i = 0; i < G.deckCount[currPlayer]; i++) {
				G.deck[currPlayer][i] = floor(Random() * (treasure_map + 1));
			}

			G.discardCount[currPlayer] = floor(Random() * MAX_DECK); // randomize # of cards in discard for player
			//set each card in the player discard to a random card from curse to treasure_map (based on the enum in dominion.h)
			for (i = 0; i < G.discardCount[currPlayer]; i++) {
				G.discard[currPlayer][i] = floor(Random() * (treasure_map + 1));
			}

			G.handCount[currPlayer] = floor(Random() * MAX_HAND); // randomize # of cards in player hand
			//set each card in the player hand to a random card from curse to treasure_map (based on the enum in dominion.h)
			for (i = 0; i < G.handCount[currPlayer]; i++) {
				G.hand[currPlayer][i] = floor(Random() * (treasure_map + 1));
			}
		}

		handPos = 0;
		c1 = -1;
		c2 = -1;
		c3 = -1;

		G.phase = 0;
		G.numActions = 1;

		// set phase to buy so that first if-statement in playCard fails
		if (fixedCounter == 0) {
			G.phase = 1;
		}
		// set action points to zero so that second if-statement fails
		else if (fixedCounter == 1) {
			G.numActions = 0;
		}
		// set card that will be played to NOT an action card, failing third if-statement
		else if (fixedCounter == 2) {
			G.hand[p][handPos] = copper;
		}
		// set card that will be play a card with invalid choices, failing fourth if-statement
		else if (fixedCounter == 3) {
			G.hand[p][handPos] = ambassador;
			c1 = handPos;
			c2 = 4;
		}
		// play an action card successfully
		else if (fixedCounter == 4) {
			G.hand[p][handPos] = council_room;
		}
		// test playCard with random inputs
		else {
			handPos = floor(Random() * G.handCount[p]); // randomize hand pos for current player's turn
			c1 = floor(Random() * MAX_HAND);
			c2 = floor(Random() * MAX_HAND);
			c3 = floor(Random() * MAX_HAND);
		}

		x = playCard(handPos, c1, c2, c3, &G);

		// for the first four fixed tests, test passes if playCard returns -1
		if (fixedCounter >= 0 && fixedCounter <= 3) {
			if (x == -1) testPassed++;
			else {
				testFailed++;
				if (fixedCounter == 0) printf("Fixed Test #1 Failed\n");
				if (fixedCounter == 1) printf("Fixed Test #2 Failed\n");
				if (fixedCounter == 2) printf("Fixed Test #3 Failed\n");
				if (fixedCounter == 3) printf("Fixed Test #4 Failed\n");
			}
			fixedCounter++;
		}
		// for the fifth fifth fixed test, test passes if playCard returns 0
		else if (fixedCounter == 4) {
			if (x == 0) testPassed++;
			else { 
				testFailed++;
				printf("Fixed Test #5 Failed\n");
			}
			fixedCounter++;
		}
		// for the random tests, test passes if playCard returns 0 or -1
		else {
			if (x == 0 || x == -1) testPassed++;
			else testFailed++;
		}

		// check state of numActions and make sure it decremented by 1

    }

	printf("%d tests completed - %d tests passed - %d tests failed\n", testCount, testPassed, testFailed);

    return 0;
}
